package com.zenithmind.note.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.note.mapper.NoteLikeMapper;
import com.zenithmind.note.mapper.NoteMapper;
import com.zenithmind.note.pojo.entity.Note;
import com.zenithmind.note.pojo.entity.NoteLike;
import com.zenithmind.note.service.NoteLikeService;
import com.zenithmind.common.annotation.DataCache;
import com.zenithmind.common.annotation.DataCacheEvict;
import com.zenithmind.common.constant.CacheConstants;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 笔记点赞服务实现类
 * 
 * @author zenithmind
 * @since 2023-06-12
 */
@Slf4j
@Service
public class NoteLikeServiceImpl extends ServiceImpl<NoteLikeMapper, NoteLike> implements NoteLikeService {

    @Autowired
    private NoteMapper noteMapper;
    
    // 缓存相关常量
    private static final String CACHE_NOTE_LIKE_PREFIX = "note:like";
    private static final String CACHE_USER_LIKE_PREFIX = "user:like";
    
    /**
     * 判断用户是否点赞了笔记
     */
    @Override
    @DataCache(prefix = CACHE_NOTE_LIKE_PREFIX, key = "#noteId + ':' + #userId", expireTime = CacheConstants.TTL_SECONDS_USER)
    public boolean isLiked(String noteId, String userId) {
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(noteId)) {
            return false;
        }
        
        LambdaQueryWrapper<NoteLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NoteLike::getNoteId, noteId)
                .eq(NoteLike::getUserId, userId);
        return count(wrapper) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DataCacheEvict(prefix = CACHE_NOTE_LIKE_PREFIX, key = "#noteId + ':' + #userId")
    public boolean addLike(String noteId, String userId) {
        // 检查是否已点赞
        if (isLiked(noteId, userId)) {
            return false;
        }
        
        // 添加点赞记录
        NoteLike noteLike = new NoteLike();
        noteLike.setNoteId(noteId);
        noteLike.setUserId(userId);
        boolean saved = save(noteLike);
        
        if (saved) {
            // 更新笔记点赞数
            LambdaUpdateWrapper<Note> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Note::getId, noteId)
                        .setSql("like_count = like_count + 1");
            noteMapper.update(null, updateWrapper);
        }
        
        return saved;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DataCacheEvict(prefix = CACHE_NOTE_LIKE_PREFIX, key = "#noteId + ':' + #userId")
    public boolean cancelLike(String noteId, String userId) {
        // 查询点赞记录
        LambdaQueryWrapper<NoteLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NoteLike::getNoteId, noteId)
                .eq(NoteLike::getUserId, userId);
        
        NoteLike noteLike = getOne(wrapper);
        if (noteLike == null) {
            return false;
        }
        
        // 删除点赞记录
        boolean removed = removeById(noteLike.getId());
        
        if (removed) {
            // 更新笔记点赞数
            LambdaUpdateWrapper<Note> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Note::getId, noteId)
                        .setSql("like_count = like_count - 1");
            noteMapper.update(null, updateWrapper);
        }
        
        return removed;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DataCacheEvict(prefix = CACHE_NOTE_LIKE_PREFIX, allEntries = true)
    public boolean deleteByNoteId(String noteId) {
        if (StringUtils.isBlank(noteId)) {
            return false;
        }
        
        LambdaQueryWrapper<NoteLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NoteLike::getNoteId, noteId);
        boolean removed = remove(wrapper);
        
        if (removed) {
            // 重置笔记点赞数
            Note note = noteMapper.selectById(noteId);
            if (note != null) {
                note.setLikeCount(0);
                noteMapper.updateById(note);
            }
        }
        
        return removed;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    @DataCacheEvict(prefix = CACHE_USER_LIKE_PREFIX, key = "#userId")
    public boolean deleteByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return false;
        }
        
        LambdaQueryWrapper<NoteLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(NoteLike::getUserId, userId);
        return remove(wrapper);
    }
} 